package cn.itcast.n8;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.StampedLock;

import static cn.itcast.n2.util.Sleeper.sleep;

/**
 * @author: AirMan
 * @date: 2025/4/25 12:43
 * @description:
 */


@Slf4j(topic = "c.TestStampedLock_my")
public class TestStampedLock_my {


    public static void main(String[] args) {

        DataContainerScan dataContainerScan = new DataContainerScan();

        new Thread(() -> {
            dataContainerScan.read();
        }, "t1").start();
        sleep(1);
        new Thread(() -> {
            dataContainerScan.read();
        }, "t2").start();
        new Thread(() -> {
            dataContainerScan.write(1);
        }, "t2").start();
    }

    static class DataContainerScan {
        private int data;
        private StampedLock lock = new StampedLock();

        private int read() {
            long stamp = lock.tryOptimisticRead();
            log.debug("read data...");
            sleep(1);
            if (lock.validate(stamp)) {
                log.debug("read finished...{}" + stamp);
                return data;
            }
            log.debug("updating to read lock...{}", stamp);
            try {
                stamp = lock.readLock();
                log.debug("read lock...{}", stamp);
                log.debug("read finished...{}", stamp);
                return data;
            } finally {
                lock.unlock(stamp);
            }
        }


        private void write(int wData) {
            long stamp = lock.writeLock();
            try {
                log.debug("write lock...{}", stamp);
                sleep(2);
                this.data = wData;
            } finally {
                log.debug("wrire unlock...{}", stamp);
                lock.unlock(stamp);
            }
        }


    }

}
